package configClient;

import lombok.extern.slf4j.Slf4j;

import java.sql.Date;
import java.sql.ResultSet;

import static configClient.MysqlExecuteHelper.executeQuery;
import static java.lang.String.format;
import static java.util.Optional.ofNullable;

/**
 * Mysql 配置中心客户端
 */

@Slf4j
public class MySqlConfigClient extends BaseConfigClient {

    /**
     * 查询 configKey 源信息 模板 SQL
     */

    private static final String QUERY_CONFIG_META_INFO_TEMPLATE_SQL =
            "SELECT version, update_time, create_time " +
                    "FROM %s " +
                    "WHERE config_key = %s";

    /**
     * 查询 configKey 对应的 value 模板 SQL
     */

    private static final String QUERY_CONFIG_VALUE_TEMPLATE_SQL =
            "SELECT config_value " +
                    "FROM %s " +
                    "WHERE config_key = %s";

    private final String ip;
    private final String port;
    private final String username;
    private final String password;
    private final String tableName;
    private final String dataBase;

    public MySqlConfigClient(String configKey,
                             String ip,
                             String port,
                             String username,
                             String password,
                             String tableName,
                             String dataBase) {
        super(configKey);
        this.ip = ip;
        this.port = port;
        this.username = username;
        this.password = password;
        this.tableName = tableName;
        this.dataBase = dataBase;
    }

    @Override
    protected String doGetConfig(String configKey) {

        String querySql = format(QUERY_CONFIG_VALUE_TEMPLATE_SQL, tableName, configKey);

        ResultSet resultSet = executeQuery(ip, password, username, password, dataBase, querySql);

        return ofNullable(resultSet)
                .map(rs -> {
                    try {
                        String configValue = null;
                        // 这里其实只有一条
                        while (rs.next()) {
                            configValue = rs.getString("config_value");
                            if (configValue != null) {
                                break;
                            }
                        }
                        return configValue;
                    } catch (Exception e) {
                        log.error("mysqlConfigClient doGetConfig fail, configKey : {}, ip : {}, port : {}, dataBase : {}, querySql : {}",
                                getConfigKey(),
                                ip,
                                port,
                                dataBase,
                                querySql,
                                e
                        );
                        return null;
                    }
                })
                .orElse(null);
    }

    @Override
    public ConfigMetaInfo getRemoteConfigMetaInfo(String configKey) {
        String querySql = format(QUERY_CONFIG_META_INFO_TEMPLATE_SQL, tableName, configKey);

        ResultSet resultSet = executeQuery(ip, password, username, password, dataBase, querySql);

        return ofNullable(resultSet)
                .map(rs -> {
                    try {
                        ConfigMetaInfo configMetaInfo = new ConfigMetaInfo();
                        // 这里其实只有一条
                        while (rs.next()) {
                            Long version = rs.getLong("version");
                            Date updateTime = rs.getDate("update_time");
                            Date createTime = rs.getDate("create_time");
                            configMetaInfo.setCreateTime(createTime);
                            configMetaInfo.setVersion(version);
                            configMetaInfo.setUpdateTime(updateTime);
                        }
                        return configMetaInfo;
                    } catch (Exception e) {
                        log.error("mysqlConfigClient getConfigMetaInfo fail, configKey : {}, ip : {}, port : {}, dataBase : {}, querySql : {}",
                                getConfigKey(),
                                ip,
                                port,
                                dataBase,
                                querySql,
                                e
                        );
                        return null;
                    }
                })
                .orElse(null);
    }
}
